﻿using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.ComponentModel.Composition;
using ScrumFactory.Composition.ViewModel;
using ScrumFactory.Composition;
using ScrumFactory.Windows.Helpers;
using ScrumFactory.Services;
using System.Linq;
using ScrumFactory.Composition.View;
using System.Windows.Data;
using System.Windows.Input;

namespace ScrumFactory.Projects.ViewModel {
    
    [Export]
    [Export(typeof(IDockPanelViewModel))]
    public class MyDayViewModel : BasePanelViewModel, IDockPanelViewModel, INotifyPropertyChanged {

        private IEventAggregator aggregator;
        private ITasksService tasksService;
        private IProjectsService projectsService;
        private IBackgroundExecutor executor;
        private IAuthorizationService authorizator;

        private ICollection<Task> myTasks;
        private ICollection<Task> myOwnedTasks;
        private ICollection<ProjectEvent> projectEvents;
        

        [ImportingConstructor()]
        public MyDayViewModel(
            [Import] IEventAggregator aggregator,
            [Import] ITasksService tasksService,
            [Import] IProjectsService projectsService,
            [Import] IBackgroundExecutor executor,
            [Import] IAuthorizationService authorizator) {

                this.executor = executor;
                this.aggregator = aggregator;
                this.tasksService = tasksService;
                this.projectsService = projectsService;
                this.authorizator = authorizator;

                OnLoadCommand = new DelegateCommand(() => { if(NeedRefresh) Load(); });
                ShowTaskDetailCommand = new DelegateCommand<Task>(ShowTaskDetail);
                ShowProjectDetailCommand = new DelegateCommand<string>(ShowProjectDetail);

        }

        private System.DateTime lastRefreshDate;

        public override bool NeedRefresh {
            get {
                return System.DateTime.Now.Subtract(lastRefreshDate).TotalSeconds > 10;
            }
            set {
                if (value == false)
                    lastRefreshDate = System.DateTime.Now;
                base.NeedRefresh = value;
            }
        }


        public ICollection<Task> MyTasks {
            get {
                return myTasks;
            }
            set {                
                myTasks = value;                
                OnPropertyChanged("MyTasks");
            }
        }

        public ICollection<Task> MyOwnedTasks {
            get {
                return myOwnedTasks;
            }
            set {                
                myOwnedTasks = value;                
                OnPropertyChanged("MyOwnedTasks");
            }
        }

        public ICollection<ProjectEvent> ProjectEvents {
            get {
                return projectEvents;
            }
            set {            
                projectEvents = value;                
                OnPropertyChanged("ProjectEvents");
            }
        }

        public string TodayHeader {
            get {
                return System.DateTime.Today.ToLongDateString();
            }
        }

        private void ShowTaskDetail(Task task) {
            aggregator.Publish<Task>(ScrumFactoryEvent.ShowTaskDetail, task);
        }

        private void ShowProjectDetail(string projectUId) {
            executor.StartBackgroundTask<Project>(
                () => { return projectsService.GetProject(projectUId); },
                p => { aggregator.Publish<Project>(ScrumFactoryEvent.ViewProjectDetails, p); });
        }

        private void Load() {


            LoadMyTasks();
            LoadMyOwnedTasks();
            LoadEvents();

            NeedRefresh = false;
        }

        private void LoadMyTasks() {
            IsLoadingData = true;
            executor.StartBackgroundTask<ICollection<Task>>(
                () => { return tasksService.GetUserTasks(); },
                tasks => {                    
                    MyTasks = new List<Task>(tasks.OrderBy(t => t.Priority).ThenByDescending(t => t.TaskType));
                    
                    IsLoadingData = false;
                });
        }

        private void LoadMyOwnedTasks() {
            IsLoadingData = true;

            executor.StartBackgroundTask<ICollection<Task>>(
                () => { return tasksService.GetUserOwnedTasks(); },
                tasks => {
                    MyOwnedTasks = new List<Task>(tasks.OrderBy(t => t.Priority).ThenByDescending(t => t.TaskType));                   
                    IsLoadingData = false;
                });
        }

        private void LoadEvents() {
            IsLoadingData = true;

            executor.StartBackgroundTask<ICollection<ProjectEvent>>(
                () => { return projectsService.GetUserProjectEvents(); },
                events => {
                    ProjectEvents = new ObservableCollection<ProjectEvent>(events.OrderBy(t => t.When));
                    
                    IsLoadingData = false;
                });
        }


        public string PanelName {
            get { return Properties.Resources.My_day; }
        }

        public int PanelDisplayOrder {
            get { return 100; }
        }

        public DockPanelPlacements PanelPlacement {
            get { return DockPanelPlacements.DockPanelLeft; }
        }

        public string ImageUrl {
            get {
                return "\\Images\\Toolbar\\PostitView.png";
            }
        }

        [Import(typeof(MyDay))]
        public IView View { get; set; }


        public ICommand OnLoadCommand { get; set; }
        public ICommand ShowTaskDetailCommand { get; set; }
        public ICommand ShowProjectDetailCommand { get; set; }
    }
}
